package com.qc31.monitorlib.ui.carmonitor

import android.Manifest
import android.content.Context
import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.SeekBar
import android.widget.TextView
import androidx.core.view.isVisible
import androidx.fragment.app.Fragment
import androidx.fragment.app.activityViewModels
import androidx.fragment.app.viewModels
import androidx.lifecycle.Lifecycle
import androidx.recyclerview.widget.GridLayoutManager
import autodispose2.androidx.lifecycle.AndroidLifecycleScopeProvider
import autodispose2.autoDispose
import com.kingja.loadsir.core.LoadService
import com.kingja.loadsir.core.LoadSir
import com.qc31.baselib.interfaces.SimpleSeekBarChangeListener
import com.qc31.baselib.loadsie.EmptyCallback
import com.qc31.baselib.utils.isAppOnForeground
import com.qc31.baselib.utils.startActivityTo
import com.qc31.baselib.utils.toast
import com.qc31.comlib.Keys
import com.qc31.comlib.UrlUtil
import com.qc31.comlib.UserConstant
import com.qc31.comlib.entity.RealVideoInfo
import com.qc31.monitorlib.ui.video.TalkHelper
import com.qc31.monitorlib.R
import com.qc31.monitorlib.databinding.FragmentRealVideoBinding
import com.qc31.monitorlib.ui.adapter.RealVideoAdapter
import com.qc31.monitorlib.ui.popup.PopupActivity
import com.qc31.monitorlib.ui.video.AudioPlayer
import com.qc31.monitorlib.ui.video.RealVideoManager
import com.qc31.monitorlib.ui.video.observer.ChooseVideoUtil
import com.qc31.monitorlib.ui.video.observer.NeedMutesUtil
import com.tbruyelle.rxpermissions3.RxPermissions
import io.reactivex.rxjava3.android.schedulers.AndroidSchedulers
import java.util.*

/** @Author Jasper @Time 2020/7/22 @Desc 车辆 实时视频 */
class CarRealVideoFragment : Fragment() {

    private var mAdapter: RealVideoAdapter? = null
    private lateinit var mContext: Context
    private val mViewModel by viewModels<CarRealVideoViewModel>()
    private val mActivityVM by activityViewModels<CarMonitorViewModel>()
    private val talkHelper by lazy { TalkHelper() }

    private var uuid: String = ""


    protected var binding: FragmentRealVideoBinding? = null
    protected lateinit var loadService: LoadService<Any>

    private var isFirstLoad = true // 是否第一次加载
    protected val scopeProvider: AndroidLifecycleScopeProvider by lazy {
        AndroidLifecycleScopeProvider.from(this, Lifecycle.Event.ON_DESTROY)
    }


    override fun onCreateView(
        inflater: LayoutInflater,
        container: ViewGroup?,
        savedInstanceState: Bundle?
    ): View? {
        binding = FragmentRealVideoBinding.inflate(inflater, container, false)
        loadService = LoadSir.getDefault().register(binding!!.root)
        return loadService.loadLayout
    }

    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
        super.onViewCreated(view, savedInstanceState)
        initView()
    }

    override fun onResume() {
        super.onResume()
        if (isFirstLoad) {
            // 将数据加载逻辑放到onResume()方法中
            initData()
            initEvent()
            isFirstLoad = false
        }
    }

    fun initView() {
        mContext = requireContext()
        binding?.recyclerVideo?.layoutManager = GridLayoutManager(mContext, 2)

        ChooseVideoUtil.instance.setOnVideoIndexListener(object :
            ChooseVideoUtil.OnVideoIndexListener {
            override fun onChange(index: Int) {
                mViewModel.channel = mAdapter?.data?.get(index)?.videoPass ?: ""
                val action = mViewModel.getAction()
                binding?.ivLight?.isSelected = action.light == 1
                binding?.ivWiper?.isSelected = action.wiper == 1
            }
        })

        ChooseVideoUtil.instance.setOnTalkListener(object :
            ChooseVideoUtil.OnTalkListener {
            override fun onChange(isTalk: Boolean) {
                isRecord = true
                closeTalk()
            }
        })
    }

    fun initData() {
        initRecyclerView()
        mActivityVM.carId.observe(this) { mViewModel.carId = it }
        mActivityVM.videos.observe(this) {
            mViewModel.clearMap()
            binding?.llControl?.isVisible = false
            binding?.llControl?.isEnabled = true
            binding?.llRealVideoTalk?.isEnabled = true
            binding?.llRealVideoInfo?.isEnabled = true
            mViewModel.videos = it ?: ""
            if (it.isNullOrEmpty()) {
                loadService.setCallBack(EmptyCallback::class.java) { context, view ->
                    val empty = view.findViewById<TextView>(R.id.tv_empty)
                    empty.text = getString(R.string.desc_choose_not_video_car)
                }
                loadService.showCallback(EmptyCallback::class.java)
            } else {
                loadService.showSuccess()
                mAdapter?.carId = mViewModel.carId
                mAdapter?.setList(mViewModel.handleVideos())
            }
        }
        if (mViewModel.carId.isEmpty()) {
            loadService.setCallBack(EmptyCallback::class.java) { context, view ->
                val empty = view.findViewById<TextView>(R.id.tv_empty)
                empty.text = getString(R.string.hint_toast_choose_car)
            }
            loadService.showCallback(EmptyCallback::class.java)
        }
        mViewModel.actionLive.observe(this) {
            val action = mViewModel.getAction()
            binding?.ivLight?.isSelected = action.light == 1
            binding?.ivWiper?.isSelected = action.wiper == 1
        }

        //上传PCM数据网络失败监听
        talkHelper.talkObserver().observeOn(AndroidSchedulers.mainThread())
            .autoDispose(scopeProvider).subscribe {
            isRecord = true
            closeTalk()
            binding?.llAudio?.isVisible = false
            binding?.llRealVideoInfo?.isEnabled = true
            binding?.lltvControl?.isEnabled = true
        }
    }

    fun initEvent() {

        binding?.llRealVideoInfo?.setOnClickListener {
            if (mViewModel.carId.isEmpty()) {
                R.string.hint_toast_choose_car.toast(mContext)
                return@setOnClickListener
            }
            startActivityTo<PopupActivity>(requireContext()) {
                putExtra(Keys.INTENT_CAR_ID, mViewModel.carId)
            }

        }

        binding?.llRealVideoTalk?.setOnClickListener {
            if (mViewModel.isParamsOk()) return@setOnClickListener
            if (isRecord) {
                binding?.llRealVideoInfo?.isEnabled = false
                binding?.lltvControl?.isEnabled = false
                getPermissions()
            } else {
                isRecord = true
                closeTalk()
                binding?.llRealVideoInfo?.isEnabled = true
                binding?.lltvControl?.isEnabled = true
            }
        }

        binding?.lltvControl?.setOnClickListener {
            if (mViewModel.isParamsOk()) return@setOnClickListener
            val visible = binding?.llControl?.isVisible ?: false
            binding?.llRealVideoInfo?.isEnabled = visible
            binding?.llRealVideoTalk?.isEnabled = visible

            binding?.llControl?.isVisible = !visible
            binding?.tvControl?.isSelected = !visible
            binding?.ivControl?.isSelected = !visible
            val action = mViewModel.getAction()
            binding?.ivLight?.isSelected = action.light == 1
            binding?.ivWiper?.isSelected = action.wiper == 1
        }

        binding?.vUp?.setOnClickListener { mViewModel.control(1) }
        binding?.vLeft?.setOnClickListener { mViewModel.control(3) }
        binding?.vCenter?.setOnClickListener { mViewModel.control(0) }
        binding?.vRight?.setOnClickListener { mViewModel.control(4) }
        binding?.vDown?.setOnClickListener { mViewModel.control(2) }

        binding?.ivFocalUp?.setOnClickListener {
            mViewModel.changeAction(1, 1)
        }
        binding?.ivFocalDown?.setOnClickListener {
            mViewModel.changeAction(1, 0)
        }
        binding?.ivApertureUp?.setOnClickListener {
            mViewModel.changeAction(2, 0)
        }
        binding?.ivApertureDown?.setOnClickListener {
            mViewModel.changeAction(2, 1)
        }
        binding?.ivZoomUp?.setOnClickListener {
            mViewModel.changeAction(5, 0)
        }
        binding?.ivZoomDown?.setOnClickListener {
            mViewModel.changeAction(5, 1)
        }
        binding?.ivLight?.setOnClickListener {
            val light = mViewModel.getAction().light
            if (light == 0) {
                mViewModel.changeAction(4, 1)
            } else {
                mViewModel.changeAction(4, 0)
            }
        }

        binding?.ivWiper?.setOnClickListener {
            val wiper = mViewModel.getAction().wiper
            if (wiper == 0) {
                mViewModel.changeAction(3, 1)
            } else {
                mViewModel.changeAction(3, 0)
            }
        }
        binding?.sbSpeed?.setOnSeekBarChangeListener(object : SimpleSeekBarChangeListener {
            override fun onProgressChanged(seekBar: SeekBar?, progress: Int, fromUser: Boolean) {
                super.onProgressChanged(seekBar, progress, fromUser)
                mViewModel.speed = seekBar?.progress ?: 0
                binding?.tvSpeedNum?.text = mViewModel.speed.toString()
            }
        })
    }

    private var isRecord = true
    private fun getPermissions() {
        RxPermissions(this).request(
            Manifest.permission.RECORD_AUDIO, Manifest.permission.READ_EXTERNAL_STORAGE
        ).autoDispose(AndroidLifecycleScopeProvider.from(this, Lifecycle.Event.ON_DESTROY))
            .subscribe {
                if (it) {
                    isRecord = false
                    if (mViewModel.audioPass.isNullOrEmpty()) return@subscribe
                    binding?.tvRealVideoTalk?.isSelected = true
                    binding?.ivRealVideoTalk?.isSelected = true
                    binding?.tvRealVideoTalk?.setText(R.string.desc_video_car_talk_close)
                    uuid = UUID.randomUUID().toString()
                    initVideo()
                }
            }
    }

    private fun initRecyclerView() {
        mAdapter = RealVideoAdapter(UserConstant.current_userId, mViewModel.carId)
        binding?.recyclerVideo?.adapter = mAdapter
        val view =
            LayoutInflater.from(mContext)
                .inflate(R.layout.food_view, binding?.recyclerVideo, false)
        mAdapter!!.addFooterView(view)
    }

    fun stopVideos() {
        RealVideoManager.clearAllVideo()
        closeVideos()
        if (binding == null) return
        isRecord = true
        closeTalk()

        binding?.llControl?.isEnabled = true
        binding?.llRealVideoTalk?.isEnabled = true
        binding?.llRealVideoInfo?.isEnabled = true

        binding?.llControl?.isVisible = false
        binding?.tvControl?.isSelected = false
        binding?.ivControl?.isSelected = false
    }

    private fun closeVideos() {
        if (mAdapter != null) {
            val entitys: MutableList<RealVideoInfo> = mAdapter?.data ?: return
            for (entity in entitys) {
                if (entity.uuid.isEmpty()) continue
                mViewModel.closeVideo(entity.uuid)
            }
        }
    }

    override fun onHiddenChanged(hidden: Boolean) {
        super.onHiddenChanged(hidden)
        if (hidden) {
            stopVideos()
        } else {
            mAdapter?.setList(mViewModel.handleVideos())
        }
    }

    override fun onPause() {
        super.onPause()
        binding?.recyclerVideo?.postDelayed({
            if (!isAppOnForeground(mContext)) {
                RealVideoManager.clearAllVideo(audioPlayer?.getKey())
                closeVideos()
            }
        }, 500)
    }

    override fun onDestroyView() {
        stopVideos()
        mAdapter = null
        NeedMutesUtil.instance.clearAll()
        ChooseVideoUtil.instance.clearAll()
        talkHelper.destroy()
        isFirstLoad = true
        binding = null
        super.onDestroyView()
    }
//////////////////////////////////////////////对讲/////////////////////////////////////////////////

    /** 获取播放视频参数 */
    private fun getPlayParams(): String {
        return "${UrlUtil.mVideoHost}/httpflv.talk_open.$uuid.${UserConstant.current_userId}" +
                ".${mViewModel.carId}.${mViewModel.audioPass}"
    }

    private var audioPlayer: AudioPlayer? = null
    private fun initVideo() {
        binding?.llAudio?.isVisible = true
        binding?.tvAudio?.setText(R.string.toast_audio_link)

        audioPlayer = audioPlayer ?: AudioPlayer(mContext)

        audioPlayer?.run {
            attachObserver()
            setMute(false)
            setUp(getPlayParams(), false, "video")
            setAudioCallBack(object : AudioPlayer.AudioCallBack {
                override fun finishTalk() {
                    binding?.tvAudio?.setText(R.string.toast_audio_close)
                    closeAudioVideo()
                }

                override fun failure() {
                    binding?.tvAudio?.setText(R.string.toast_audio_faile)
                    binding?.tvAudio?.postDelayed({
                        closeAudioVideo()
                    }, 2000)

                }

                override fun success() {
                    talkHelper.start("${UrlUtil.mVideoHost}/microphone.$uuid")
                    binding?.tvAudio?.setText(R.string.toast_audio_talking)
                }
            })
            startPlayLogic()
        }
    }

    private fun closeTalk() {
        closeAudioVideo()
        mViewModel.closeAudio(uuid)
    }

    private fun closeAudioVideo() {
        binding?.llAudio?.isVisible = false
        binding?.tvRealVideoTalk?.setText(R.string.desc_video_car_talk_open)
        talkHelper.stopRecord()
        binding?.tvRealVideoTalk?.isSelected = false
        binding?.ivRealVideoTalk?.isSelected = false
        audioPlayer?.releaseVideos()
        audioPlayer?.release()
        audioPlayer = null
    }
}